import { ref, onUnmounted } from 'vue'

// 用于存储全局唯一实例
let _singleton = null

// 从环境变量读取默认 Socket URL
const DEFAULT_SOCKET_URL = import.meta.env.VITE_SOCKET_URL || 'http://localhost:3000'

export default function useSocket(url = DEFAULT_SOCKET_URL, options = {}) {
  // 已有单例就直接返回
  if (_singleton) return _singleton

  // ====== 原有 hook 逻辑 ======
  const socket = ref(null)
  const connected = ref(false)
  const connecting = ref(false)
  const error = ref(null)
  const listeners = ref(new Map())

  // 连接方法
  const connect = () => {
    if (socket.value?.connected || connecting.value) return
    if (typeof window === 'undefined' || !window.io) {
      error.value = new Error('Socket.io 未加载，请确保已引入 socket.io.min.js')
      return
    }
    connecting.value = true
    error.value = null
    try {
      socket.value = window.io(url, {
        transports: ['websocket', 'polling'],
        autoConnect: true,
        reconnection: true,
        reconnectionAttempts: 5,
        reconnectionDelay: 1000,
        reconnectionDelayMax: 5000,
        timeout: 20000,
        ...options
      })
      socket.value.on('connect', () => {
        connected.value = true
        connecting.value = false
        error.value = null
      })
      socket.value.on('connect_error', (err) => {
        connected.value = false
        connecting.value = false
        error.value = err
      })
      socket.value.on('disconnect', (reason) => {
        connected.value = false
        connecting.value = false
      })
      socket.value.on('reconnect_failed', () => {
        connecting.value = false
      })
    } catch (err) {
      connecting.value = false
      error.value = err
    }
  }

  // 断开连接
  const disconnect = () => {
    if (socket.value) {
      clearAllListeners()
      socket.value.disconnect()
      socket.value = null
      connected.value = false
      connecting.value = false
    }
  }

  // 发送消息
  const emit = (event, ...args) => {
    if (!socket.value || !connected.value) return false
    try {
      socket.value.emit(event, ...args)
      return true
    } catch (err) {
      return false
    }
  }

  // 监听事件
  const on = (event, callback) => {
    if (!socket.value) return () => {}
    socket.value.on(event, callback)
    if (!listeners.value.has(event)) listeners.value.set(event, [])
    listeners.value.get(event).push(callback)
    return () => off(event, callback)
  }

  // 只监听一次
  const once = (event, callback) => {
    if (!socket.value) return
    socket.value.once(event, callback)
  }

  // 取消事件监听
  const off = (event, callback) => {
    if (!socket.value) return
    if (callback) {
      socket.value.off(event, callback)
      const arr = listeners.value.get(event)
      if (arr) arr.splice(arr.indexOf(callback), 1)
      if (arr && arr.length === 0) listeners.value.delete(event)
    } else {
      socket.value.off(event)
      listeners.value.delete(event)
    }
  }

  // 移除所有事件
  const clearAllListeners = () => {
    if (!socket.value) return
    listeners.value.forEach((arr, event) => {
      arr.forEach(cb => socket.value.off(event, cb))
    })
    listeners.value.clear()
    socket.value.off('connect')
    socket.value.off('disconnect')
    socket.value.off('error')
  }

  // 获取id
  const getSocketId = () => {
    return socket.value?.id || null
  }

  // 组件卸载时自动断开（页面用时慎用）
  // onUnmounted(disconnect)

  // 单例对象内暴露接口
  _singleton = {
    socket,
    connected,
    connecting,
    error,
    connect,
    disconnect,
    emit,
    on,
    once,
    off,
    clearAllListeners,
    getSocketId
  }
  return _singleton
}

